#pragma once
#include "fields.hpp"
#include <memory>
#include <functional>

namespace RPC
{
    //消息: 设置id, 返回id, 设置类型, 返回类型, 序列化, 反序列化, 检查;
    class BaseMessage
    {
    public:
        //大家需要的功能先实现;
        using ptr = std::shared_ptr<BaseMessage>;//定义一个指针;
        virtual ~BaseMessage(){}

        virtual void setId(const std::string& id)
        {
            _rid = id;
        }

        virtual std::string rid()
        {
            return _rid;
        }

        virtual void setMType(MType mtype)
        {
            _mtype = mtype;
        }

        virtual MType mtype()
        {
            return _mtype;
        }


        //序列化;
        virtual std::string serialize() = 0;

        //反序列化;
        virtual bool unserialize(const std::string& msg) = 0;
    
        //对消息进行检验;
        virtual bool check() = 0;
    private:
        MType _mtype;//消息类型
        std::string _rid;//id号
    };

    //缓冲区的抽象, 缓冲区大小, 读取数据, 删除数据, 读取并删除数据;
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;//定义一个指针;
        virtual size_t readableSize() = 0;//缓冲区可使用大小
        virtual int32_t peekInt32() = 0;//读取前4字节数据;
        virtual void retriveInt32() = 0;//删除前4字节数据;
        virtual int32_t readInt32() = 0;//读取并且删除前4字节数据.
        virtual std::string retrieveAsString(size_t len) = 0;
    };

     
    //通信协议, 判断是否可传输, 传输信息, 信息前序列化.
    class BaseProtocal
    {
    public:
        using ptr = std::shared_ptr<BaseProtocal>;

        virtual bool canProcessed(const BaseBuffer::ptr& buf) = 0;//可以进行传输数据的大小s;
        virtual bool onMessage(const BaseBuffer::ptr& buf, BaseMessage::ptr& msg) = 0;//接收数据进行处理.
        virtual std::string serialize(const BaseMessage::ptr& msg) = 0;//发送数据前进行序列化
    };

    //连接, 发送数据, 关闭, 连接状态.
    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;

        virtual void send(const BaseMessage::ptr& msg) = 0;
        virtual void shutdown() = 0;    
        virtual bool connected() = 0;
    };

    using ConnectionCallback = std::function<void(const BaseConnection::ptr&)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr&)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr&, BaseMessage::ptr&)>;

    //服务器; 连接回调, 关闭回调, 信息回调.
    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;

        virtual void setConnectionCallback(const ConnectionCallback& cb)
        {
            _cb_connection = cb;
        }

        virtual void setCloseCallback(const CloseCallback& cb)
        {
            _cb_close = cb;
        }

        virtual void setMessageCallback(const MessageCallback& cb)
        {
            _cb_message = cb;
        }

        virtual void start() = 0;
    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

    //客户端, 连接回调, 关闭回调, 信息回调, 连接, 关闭, 发送, 连接状态.
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;

        virtual void setConnectionCallback(const ConnectionCallback& cb)
        {
            _cb_connection = cb;
        }

        virtual void setCloseCallback(const CloseCallback& cb)
        {
            _cb_close = cb;
        }

        virtual void setMessageCallback(const MessageCallback& cb)
        {
            _cb_message = cb;
        }

        virtual void connect() = 0;
        virtual void shutdown() = 0;
        virtual bool send(const BaseMessage::ptr& msg) = 0;
        virtual BaseConnection::ptr connection() = 0;
        virtual bool connected() = 0;

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
}
